function deepPrintTable(t, indent, visited)
    visited = visited or {}
    if visited[t] then
        print(string.rep("  ", indent) .. tostring(t) .. " <cycle detected>")
        return
    end
    visited[t] = true

    indent = indent or 0
    local prefix = string.rep("  ", indent)
    for k, v in pairs(t) do
        if type(v) == "table" then
            print(prefix .. tostring(k) .. ":")
            deepPrintTable(v, indent + 1, visited)  -- 递归打印子表
        else
            print(prefix .. tostring(k) .. ": " .. tostring(v))
        end
    end
end

function printTableWithMetatableFull(t)
    -- 打印表本身
    print('\n---------------------')
    print(t)
    deepPrintTable(t, 1)

    -- 打印元表
    local mt = getmetatable(t)
    if mt ~= nil then
        deepPrintTable(mt, 1)
    end
end

-------------------------------------------
Dog = {}

function Dog:new()
    local newObj = {sound = 'woof'}
    self.__index = self
    return setmetatable(newObj, self)
end

function Dog:makeSound()
    print('I say ' .. self.sound)
end

mrDog = Dog:new()
mrDog:makeSound()

-- 测试代码
local testTable = {
    str = "hello",
    num = 42,
    bool = true,
    nilVal = nil,
    func = function() end,
    nested = {a = 1, b = {c = 2}},
    array = {10, 20, 30}
}
testTable.self = testTable -- 创建循环引用

printTableWithMetatableFull(Dog)
printTableWithMetatableFull(mrDog)
printTableWithMetatableFull(testTable)

print(package.path)  -- 输出 Lua 模块的搜索路径
print(package.cpath) -- 输出 C 模块的搜索路径

local m1 = require("mymodule")
m1.value = 2
print(m1.value)

package.loaded["mymodule"] = nil -- 清除缓存

local m2 = require("mymodule")
print(m1.value)
print(m2.value)

print('-------------------------------------------')
print("Global variables:")
printTableWithMetatableFull(_G)